package wt.hpad.model.remote;

import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import wt.hpad.model.bean.Dish;
import wt.hpad.model.bean.DishDetail;
import wt.hpad.model.bean.DishType;
import wt.hpad.model.bean.ResponseMessage;
import wt.hpad.model.bean.TableInfo;
import wt.hpad.model.remote.customParseJson.BaseConverterFactory;
import wt.hpad.model.remote.customParseJson.BaseResponseConverter;
import wt.hpad.model.remote.customParseJson.ParseMessage;
import wt.hpad.utils.DialogUtil;
import wt.hpad.utils.ThreadUtil;

import static wt.hpad.utils.LogUtil.logI;

/**
 * http 请求
 * Created by wt on 17-10-26.
 */

public class HttpUtils {
    private Retrofit mRetrofit = null;
    private String mBaseUrl = "";
    private long mStartTime;
    private Observable mObserver = null;


    public HttpUtils(String baseUrl) {
        this.mBaseUrl = baseUrl;
        mStartTime = System.currentTimeMillis();
    }

    /**
     * 初始化 retrofit 服务器
     */
    public Object setupRetrofit(Class<?> service) {
        if (mRetrofit != null) {
            mRetrofit = null;
        }
        OkHttpClient client = new OkHttpClient.Builder().
                connectTimeout(5, TimeUnit.SECONDS).
                readTimeout(60, TimeUnit.SECONDS).
                writeTimeout(60, TimeUnit.SECONDS).build();
        try {
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(mBaseUrl)
                    .addConverterFactory(new BaseConverterFactory() {
                        @Override
                        public BaseResponseConverter responseConverter() {  // 解析gson
                            return new ParseMessage();
                        }
                    })
                    .client(client)
                    .build();
            // 用Retrofit创建接口文件 , 动态代理
            return mRetrofit.create(service);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 登录并检测设备和服务器
     */
    Observable<Integer> loginAndCheckDeviceID(final Call<ResponseMessage> call) {
        try {
            mObserver = Observable.create(new ObservableOnSubscribe() {
                @Override
                public void subscribe(final ObservableEmitter e) throws Exception {
                    // 访问网络在此处,
                    call.enqueue(new Callback<ResponseMessage>() {
                        @Override
                        public void onResponse(Call<ResponseMessage> call, Response<ResponseMessage> response) {
                            try {
                                int loginResult = response.body().state;
                                e.onNext(loginResult);
                                e.onComplete();
                            } catch (Exception ex) {
                                DialogUtil.showInToast("请求url错误");
                                e.onError(new Throwable("服务器地址错误"));
                            }
                        }

                        @Override
                        public void onFailure(Call<ResponseMessage> call, Throwable t) {
                            logI("HttpUtils", "loginAndCheckDeviceID onFailure |  ", "" + t.getMessage());
                            e.onError(t);
                        }
                    });
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            long endTime = System.currentTimeMillis();
            long duration = endTime - mStartTime;
            try {
                if (duration < 2000) {
                    Thread.currentThread().sleep(2000 - duration);
                } else {
                    Thread.currentThread().sleep(2000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return mObserver;
    }

    /**
     * 获取菜单
     */
    Observable<List<Dish>> getAllDishes(final Call<ResponseMessage> call) {
        try {
            mObserver = Observable.create(new ObservableOnSubscribe() {
                @Override
                public void subscribe(final ObservableEmitter e) throws Exception {
                    call.enqueue(new Callback<ResponseMessage>() {
                        @Override
                        public void onResponse(Call<ResponseMessage> call, Response<ResponseMessage> response) {
                            try {
                                List<Dish> dishes = response.body().dataList;
                                e.onNext(dishes);
                                e.onComplete();
                            } catch (Exception ex) {
                                e.onError(new Throwable("获取菜单出错"));
                            }
                        }

                        @Override
                        public void onFailure(Call<ResponseMessage> call, Throwable t) {
                            logI("HttpUtils", "getAllDishes onFailure |  ", "" + t.getMessage());
                            ThreadUtil.runOnUI(new Runnable() {
                                @Override
                                public void run() {
                                    DialogUtil.showInToast("服务器或网络未连接");
                                }
                            });
//                            e.onError(t);
                        }
                    });
                }
            });
        } catch (Exception e) {
            DialogUtil.showInToast("获取未上菜出错");
        }
        return mObserver;
    }

    /**
     * 获取所有桌台
     */
    Observable<List<TableInfo>> getAllTableInfo(final Call<ResponseMessage> call) {
        try {
            mObserver = Observable.create(new ObservableOnSubscribe() {
                @Override
                public void subscribe(final ObservableEmitter e) throws Exception {
                    call.enqueue(new Callback<ResponseMessage>() {
                        @Override
                        public void onResponse(Call<ResponseMessage> call,
                                               Response<ResponseMessage> response) {
                            try {
                                List<TableInfo> tableInfos = response.body().dataList;
                                e.onNext(tableInfos);
                                e.onComplete();
                            } catch (Exception ex) {
                                e.onError(new Throwable("获取所有桌台出错"));
                            }
                        }

                        @Override
                        public void onFailure(Call<ResponseMessage> call, Throwable t) {
                            DialogUtil.showInToast("服务器或网络未连接");
                            e.onError(t);
                        }
                    });
                }
            });
        } catch (Exception e) {
            DialogUtil.showInToast("获取所有桌台异常");
        }
        return mObserver;
    }

    /**
     * 获取某个桌台的菜
     */
    Observable<List<DishDetail>> getTableDishes(final Call<ResponseMessage> call) {
        try {
            mObserver = Observable.create(new ObservableOnSubscribe() {
                @Override
                public void subscribe(final ObservableEmitter e) throws Exception {
                    call.enqueue(new Callback<ResponseMessage>() {
                        @Override
                        public void onResponse(Call<ResponseMessage> call,
                                               Response<ResponseMessage> response) {
                            try {
                                List<DishDetail> dishDetails = response.body().dataList;
                                if (dishDetails == null) {
                                    e.onComplete();
                                } else {
                                    // e.onNext 不允许传 null 值
                                    e.onNext(dishDetails);
                                }
                            } catch (Exception ex) {
                                e.onError(new Throwable("获取桌台所有菜出错"));
                            }
                        }

                        @Override
                        public void onFailure(Call<ResponseMessage> call, Throwable t) {
                            logI("HttpUtils", "getTableDishes onFailure |  ", "" + t.getMessage());
                            e.onError(t);
                        }
                    });
                }
            });
        } catch (Exception e) {
            DialogUtil.showInToast("获取桌台所有菜异常");
        }
        return mObserver;
    }

    /**
     * 点菜
     */
    Observable<Integer> placeOrder(final Call<ResponseMessage> call) {
        try {
            mObserver = Observable.create(new ObservableOnSubscribe() {
                @Override
                public void subscribe(final ObservableEmitter e) throws Exception {
                    call.enqueue(new Callback<ResponseMessage>() {
                        @Override
                        public void onResponse(Call<ResponseMessage> call,
                                               Response<ResponseMessage> response) {
                            try {
                                int state = response.body().state;
                                e.onNext(state);
                                e.onComplete();
                            } catch (Exception ex) {
                                e.onError(new Throwable("点菜出错"));
                            }
                        }

                        @Override
                        public void onFailure(Call<ResponseMessage> call, Throwable t) {
                            logI("HttpUtils", "placeOrder onFailure |  ", "" + t.getMessage());
                            e.onError(t);
                        }
                    });
                }
            });
        } catch (Exception e) {
            DialogUtil.showInToast("点菜异常");
        }
        return mObserver;
    }

    /**
     * 获取菜品分类数据
     */
    Observable<List<DishType>> getDishType(final Call<ResponseMessage> call) {
        try {
            mObserver = Observable.create(new ObservableOnSubscribe() {
                @Override
                public void subscribe(final ObservableEmitter e) throws Exception {
                    call.enqueue(new Callback<ResponseMessage>() {
                        @Override
                        public void onResponse(Call<ResponseMessage> call,
                                               Response<ResponseMessage> response) {
                            try {
                                List<DishType> datas = response.body().dataList;
                                e.onNext(datas);
                                e.onComplete();
                            } catch (Exception ex) {
                                e.onError(new Throwable("获取分类出错"));
                            }
                        }

                        @Override
                        public void onFailure(Call<ResponseMessage> call, Throwable t) {
                            logI("HttpUtils", "getDishType onFailure |  ", "" + t.getMessage());
                            e.onError(t);
                        }
                    });
                }
            });
        } catch (Exception e) {
            ThreadUtil.runOnUI(new Runnable() {
                @Override
                public void run() {
                    DialogUtil.showInToast("获取分类异常");
                }
            });
        }
        return mObserver;
    }

    /**
     * 退菜
     */
    Observable<Integer> retreatDish(final Call<ResponseMessage> call) {
        try {
            mObserver = Observable.create(new ObservableOnSubscribe() {
                @Override
                public void subscribe(final ObservableEmitter e) throws Exception {
                    call.enqueue(new Callback<ResponseMessage>() {
                        @Override
                        public void onResponse(Call<ResponseMessage> call,
                                               Response<ResponseMessage> response) {
                            try {
                                int state = response.body().state;
                                e.onNext(state);
                                e.onComplete();
                            } catch (Exception ex) {
                                e.onError(new Throwable("点菜出错"));
                            }
                        }

                        @Override
                        public void onFailure(Call<ResponseMessage> call, Throwable t) {
                            logI("HttpUtils", "placeOrder onFailure |  ", "" + t.getMessage());
                            e.onError(t);
                        }
                    });
                }
            });
        } catch (Exception e) {
            DialogUtil.showInToast("退菜异常");
        }
        return mObserver;
    }

    public void stopHttpRequest() {
        mRetrofit = null;
    }

}
